`
https://leetcode.cn/problems/lexicographically-smallest-string-after-applying-operations/
`

/**
 * @param {string} s
 * @param {number} a
 * @param {number} b
 * @return {string}
 */
var findLexSmallestString = function (s, a, b) {
  const visited = new Set()
  let minStr = s

  const dfs = (start) => {
    if (visited.has(start)) return

    visited.add(start)
    minStr = start < minStr ? start : minStr
    dfs(add(start, a))
    dfs(rotate(start, b))
  }
  dfs(s)

  return minStr
};

// 累加
function add(s, a) {
  return s.split('').map((val, idx) => idx % 2 !== 0 ? (+val + a) % 10 : val).join('')
}

// 轮转
function rotate(s, b) {
  const arr = s.split('')
  const n = arr.length
  b = b % n
  reverse(arr, 0, n - 1)
  reverse(arr, 0, b - 1)
  reverse(arr, b, n - 1)
  return arr.join('')
}

function reverse(arr, left, right) {
  while (left < right) {
    const temp = arr[left]
    arr[left] = arr[right]
    arr[right] = temp
    left++
    right--
  }
}